﻿using Authority.Common;
using Authority.DataTransferObject.User;
using Authority.IServices;
using Authority.IServices.Model.User;
using Authority.PresentationModels.User;
using AutoMapper;
using HelperFromTheSkeleton.APICore;
using HelperFromTheSkeleton.JwtHelper;
using HelperFromTheSkeleton.Model.PageModel;
using HelperFromTheSkeleton.Model.RequestModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.ComponentModel.DataAnnotations;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;

namespace Authority.WebAPI.Controllers
{
    /// <summary>
    /// 用户控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]
    public class UserController : BaseController
    {
        private readonly IUserService _userService;
        private readonly IMapper _mapper;
        private readonly JwtManage _jwtManage;

        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="userService"></param>
        /// <param name="mapper"></param>
        /// <param name="jwtManage"></param>
        public UserController(IUserService userService, IMapper mapper, JwtManage jwtManage)
        {
            _userService = userService;
            _mapper = mapper;
            _jwtManage = jwtManage;
        }
        /// <summary>
        /// 登录
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        public async Task<ResultModel<LogInDTO>> Login(LogInRequestModel requestModel)
        {
            return await HandleAsync(async () =>
            {
                requestModel.Password = GetMd5String(requestModel.Password);
                UserListDTO userInfo = await _userService.PasswordAertificationAsync(requestModel.Account, requestModel.Password);
                var claims = new[]
                {
                    new Claim("UserID",userInfo.ID.ToString()),
                };
                var result = new LogInDTO
                {
                    UserID = userInfo.ID,
                    UserName = userInfo.Name,
                    Token = _jwtManage.CreateToken(new Dictionary<string, string> { { "UserID", userInfo.ID.ToString() } })
                };
                return result;
            });
        }

        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="requestModel"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<Guid>> Add(AddUserRequestModel requestModel)
        {
            return await HandleAsync(async () =>
            {
                requestModel.Password = GetMd5String(requestModel.Password ?? "");
                var model = _mapper.Map<AddUserModel>(requestModel);
                return await _userService.AddAsync(model);
            });
        }

        /// <summary>
        /// 修改用户
        /// </summary>
        /// <param name="requestModel"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel> Edit(EditUserRequestModel requestModel)
        {
            return await HandleAsync(async () =>
            {
                var model = _mapper.Map<EditUserModel>(requestModel);
                await _userService.EditAsync(model);
            });
        }


        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id">用户ID</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultModel> Delete([Required] Guid id)
        {
            return await HandleAsync(async () =>
            {
                await _userService.DeleteAsync(id);
            });
        }

        /// <summary>
        /// 通过角色Code为用户新增角色
        /// </summary>
        /// <param name="requestModel"></param>
        /// <returns></returns>

        [HttpPost]
        public async Task<ResultModel> AddUserRoleByRoleCode(AddUserRoleByRoleCodeRequestModel requestModel)
        {
            return await HandleAsync(async () =>
            {
                await _userService.AddUserRoleByRoleCodeAsync(requestModel.UserIDs, requestModel.RoleCodes);
            });
        }

        /// <summary>
        /// 通过角色Code为用户删除角色
        /// </summary>
        /// <param name="requestModel"></param>
        /// <returns></returns>

        [HttpPost]
        public async Task<ResultModel> DeleteUserRoleByRoleCode(DeleteUserRoleByRoleCodeRequestModel requestModel)
        {
            return await HandleAsync(async () =>
            {
                await _userService.DeleteUserRoleByRoleCodeAsync(requestModel.UserIDs, requestModel.RoleCodes);
            });
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="ids">用户ID</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<List<UserListDTO>>> Get([Required] List<Guid> ids)
        {
            return await HandleAsync(async () =>
            {
                return await _userService.GetAsync(ids.ToArray());
            });
        }

        /// <summary>
        /// 获取登录用户信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultModel<UserListDTO?>> GetLoginUser()
        {
            return await HandleAsync(async () =>
            {
                var userID = GetUserID();
                var a = _jwtManage.ToString();
                if (userID == null) throw new InvalidOperationException("登录人获取失败");
                return (await _userService.GetAsync(new Guid[] { userID.Value })).FirstOrDefault();
            });
        }

        /// <summary>
        /// 查询用户
        /// </summary>
        /// <param name="requestModel"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResultModel<UserListDTO>> Query(QueryUserRequestModel requestModel)
        {
            return await HandleAsync(async () =>
            {
                var model = _mapper.Map<QueryUserModel>(requestModel);
                return await _userService.QueryAsync(model);
            });
        }

        /// <summary>
        /// 获取用户功能
        /// </summary>
        /// <param name="subsystemID">子系统ID</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        [HttpGet]
        public async Task<ResultModel<UserActionInfoDTO>> GetUserActionList([Required] Guid subsystemID)
        {
            return await HandleAsync(async () =>
            {
                var userID = GetUserID();
                if (!userID.HasValue) throw new InvalidOperationException("获取用户标识失败");
                return await _userService.GetUserActionAsync(userID.Value, subsystemID);
            });
        }

        /// <summary>
        /// 获取用户菜单树
        /// </summary>
        /// <param name="subsystemID">子系统ID</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        [HttpGet]
        public async Task<ResultModel<UserMenuTreeDTO>> GetUserMenuTree([Required] Guid subsystemID)
        {
            return await HandleAsync(async () =>
            {
                var userID = GetUserID();
                if (!userID.HasValue) throw new InvalidOperationException("获取用户标识失败");
                return await _userService.GetUserMenuTreeAsync(userID.Value, subsystemID);
            });
        }

        /// <summary>
        /// 获取用户菜单列表
        /// </summary>
        /// <param name="subsystemID">子系统ID</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        [HttpGet]
        public async Task<ResultModel<UserMenuListDTO>> GetUserMenuList([Required] Guid subsystemID)
        {
            return await HandleAsync(async () =>
            {
                var userID = GetUserID();
                if (!userID.HasValue) throw new InvalidOperationException("获取用户标识失败");
                return await _userService.GetUserMenuListAsync(userID.Value, subsystemID);
            });
        }

        /// <summary>
        /// 获取用户路由
        /// </summary>
        /// <param name="subsystemID">子系统ID</param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        [HttpGet]
        public async Task<ResultModel<UserRoutingListDTO>> GetUserRoutingList([Required] Guid subsystemID)
        {
            return await HandleAsync(async () =>
            {
                var userID = GetUserID();
                if (!userID.HasValue) throw new InvalidOperationException("获取用户标识失败");
                return await _userService.GetUserRoutingListAsync(userID.Value, subsystemID);
            });
        }

        /// <summary>
        /// 获取用户角色列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        [HttpGet]
        public async Task<ResultModel<UserRoleListDTO>> GetUserRoleList()
        {
            return await HandleAsync(async () =>
            {
                var userID = GetUserID();
                if (!userID.HasValue)
                {
                    var aaa = userID;
                }
                if (!userID.HasValue) throw new InvalidOperationException("获取用户标识失败");
                return await _userService.GetUserRoleListAsync(userID.Value);
            });
        }

        /// <summary>
        /// 获取用户角色列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        [HttpGet]
        public async Task<ResultModel<UserRoleListDTO>> GetUserRoleListByUserID(Guid userID)
        {
            return await HandleAsync(async () =>
            {
                return await _userService.GetUserRoleListAsync(userID);
            });
        }


        /// <summary>
        /// 获取MD5字符串
        /// </summary>
        /// <returns></returns>
        private static string GetMd5String(string text)
        {
            MD5 md5 = MD5.Create();
            byte[] encryptBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(text));
            string result = Encoding.UTF8.GetString(encryptBytes);
            return result;
        }
    }
}
